home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Belgian Amiga Club - ADF Collection
/
BS1 part 47.7z
/
BS1 part 47
/
Amiga plus 2 (1989)(Amiga Plus Magazine)[h QTX].7z
/
Amiga plus 2 (1989)(Amiga Plus Magazine)[h QTX].adf
/
Programming
/
calcffp.asm
< prev
next >
Wrap
Assembly Source File
|
1989-03-03
|
6KB
|
214 lines
;CALCFFP.ASM BY DANIEL WOLF 02/18/89
;WITH FLOATING POINT (FFP SINGLE PRECISION) CONVERSION ROUTINES BY DANIEL WOLF
;COPYRIGHT 1989 BY DANIEL WOLF Ph.D.
LVO.SPFIX EQU $FFFFFFE2 ; -30
LVO.SPFLT EQU $FFFFFFDC ; -36
LVO.SPCMP EQU $FFFFFFD6 ; -42
LVO.SPTST EQU $FFFFFFD0 ; -48
LVO.SPABS EQU $FFFFFFCA ; -54
LVO.SPNEG EQU $FFFFFFC4 ; -60
LVO.SPADD EQU $FFFFFFBE ; -66
LVO.SPSUB EQU $FFFFFFB8 ; -72
LVO.SPMUL EQU $FFFFFFB2 ; -78
LVO.SPDIV EQU $FFFFFFAC ; -84
LVO.OUTPUT EQU $FFFFFFC4 ; -60
LVO.WRITE EQU $FFFFFFD0 ; -48
LVO.OPENLIBRARY EQU $FFFFFDD8 ; -552
LVO.CLOSELIBRARY EQU $FFFFFE62 ; -414
MAIN
MOVE.L A0,A5 ;SAVE POINTER TO THE ASCII #S TYPED IN
MOVE.L $4,A6 ;USE FIXED EXECBASE POINTER
LEA DOSNAME,A1 ;OPEN DOS LIBRARY
CLR.L D0
JSR LVO.OPENLIBRARY(A6)
MOVE.L D0,A4 ;SAVE ITS BASE ADDRESS
BEQ QUIT2
LEA MATHNAME,A1 ;OPEN MATH LIBRARY
CLR.L D0
JSR LVO.OPENLIBRARY(A6)
MOVE.L D0,A3 ;SAVE ITS BASE AS WELL
BEQ QUIT1
MOVE.L A5,A0 ;NOW GET THE FIRST #
BSR ASCTOFFP ;CONVERT TO FFP FORMAT
BNE QUIT0
MOVE.L D0,D6
MOVE.L A5,A0 ;POINT A0 TO NEXT NUMBER
MOVE.B -(A5),D7 ;KEEP OPERATOR IN D7
BSR ASCTOFFP ;CONVERT 2ND # TO FFP
BNE QUIT0
MOVE.L D6,D1
EXG D0,D1
CMPI.B #'*',D7
BEQ MULTIPLYEM
CMPI.B #'/',D7
BEQ DIVIDEM
CMPI.B #'-',D7
BEQ SUBTRACTEM
ADDEM
JSR LVO.SPADD(A3)
FFPTOASC ;CONVERT RESULT IN D0 BACK TO ASCII
LEA DECBUF2,A0 ;ROUTINE GOOD FOR UP TO 16 DIGITS TOTAL ACCURACY
BTST.L #7,D0 ;IS THE FFP # NEGATIVE?
BEQ POSITIVEFFP
MOVE.B #'-',(A0) ;YES, PUT NEG SIGN INTO ASCII BUFFER
POSITIVEFFP
BCLR.L #7,D0 ;WORK WITH IT AS POSITIVE
ADDA.L #1,A0
MOVE.L D0,D7 ;HIDE IT IN D7
MOVE.L #$BEBC205B,D6 ;FIRST POWER OF 10 IS 10^8
MOVE.W #16,D4 ;MAX POWER OF 10 DIVIDES
DIVPOWEROFTEN
TST.W D4
BEQ ENDFFPTDA
SUBQ.W #1,D4 ;DEC POWER OF 10 BY 1
ADDA.L #1,A0 ;ADVANCE POINTER BY 1
CMPI.W #7,D4
BNE NOTDECPOINT
MOVE.B #'.',(A0)+
MOVE.L #$CCCCCC3D,D0 ;ONE TENTH IN FFP NOTATION
BRA PASTDECPOINT
NOTDECPOINT
MOVE.L D6,D0 ;BRING CURRENT POWER OF 10 INTO D0
MOVE.L #$A0000044,D1 ;DIVIDE BY 10 IN FFP NOTATION
JSR LVO.SPDIV(A3)
PASTDECPOINT
MOVE.B #'0',(A0) ;ZERO THIS SPOT IN THE BUFFER
MOVE.L D0,D1 ;PUT POWER OF 10 INTO D1
MOVE.L D0,D6 ;SAVE POWER OF 10 IN D6
MOVE.L D7,D0 ;PUT CURRENT VALUE OF FFP NUMBER INTO D0
COMPWITHPOWER
JSR LVO.SPCMP(A3) ;COMPARE POWER OF 10 WITH FFP NUMBER - TRASHES REGS!
BLT DIVPOWEROFTEN
SUBPOWEROFTEN
MOVE.L D7,D0 ;FFP # INTO D0
MOVE.L D6,D1 ;POWER INTO D1
JSR LVO.SPSUB(A3)
MOVE.L D0,D7 ;SAVE CURRENT VALUE OF FFP NUMBER
ADD.B #1,(A0) ;ADD 1 TO THE DIGIT AT THIS POWER OF 10
BRA COMPWITHPOWER
ENDFFPTDA
STRIP ;STRIP LEADING ZEROS IN THE ASCII BUFFER
LEA DECBUF2+1,A0
STRIPMORE
MOVE.B (A0),D0
CMPI.B #'0',D0
BNE NOWRITE
MOVE.B #' ',(A0)+
BRA STRIPMORE
NOWRITE
JSR LVO.OUTPUT(A4) ;GRAB THE OUTPUT FILE HANDLE FOR THIS CLI
MOVE.L D0,D1
MOVE.L #DECBUF,D2 ;DECBUF HAS THE ASCII RESULT OF OPERATION
MOVE.L #23,D3
JSR LVO.WRITE(A4) ;WRITE OUT THE ASCII RESULT
QUIT0
MOVE.L A3,A1 ;CLOSE DOWN LIBRARIES
JSR LVO.CLOSELIBRARY(A6)
QUIT1
MOVE.L A4,A1
JSR LVO.CLOSELIBRARY(A6)
QUIT2 ;AND HOME, JEEVES.
RTS
DIVIDEM
JSR LVO.SPDIV(A3)
BRA FFPTOASC
MULTIPLYEM
JSR LVO.SPMUL(A3)
BRA FFPTOASC
SUBTRACTEM
JSR LVO.SPSUB(A3)
BRA FFPTOASC
ASCTOFFP ;SUBROUTINE TO CONVERT ASCII TO FFP NOTATION
;ENTER W/ A0 POINTING TO ASCII DECIMAL TEXT
;EXIT WITH FFP NUMBER IN D0
;ERROR INDICATOR IS D1 - 0 MEANS OK
; 1 MEANS ERROR
CLR.L D5
CMPI.B #'-',(A0) ;IS IT A NEGATIVE NUMBER?
BNE.S CONVERTPOS
MOVE.B #128,D5 ;YES, SET UP SIGN BIT FOR CORRECTION TO RESULT
ADDA.L #1,A0 ;AND MOVE ADDRESS POINTER BEYOND THE NEG SIGN
CONVERTPOS ;CONVERT POSITIVE ASCII DECIMAL TO BINARY NUMBER
CLR.L D0 ;REGISTER TO ACCUMULATE THE BINARY CONVERSION
CLR.L D2
CLR.L D4
GETDIG
MOVE.B (A0)+,D3 ;GET ASCII DECIMAL DIGIT BYTE
CMPI.B #'.',D3 ;HIT THE DP?
BNE TESTDIG ;NOPE, GO ON
MOVEQ #1,D4 ;YUP, SET RIGHT OF DP FLAG AND GRAB ANOTHER DIGIT
CLR.L D2
BRA GETDIG
TESTDIG
CMPI.B #'9',D3 ;CHECK THAT IT IS REALLY AN ASCII DECIMAL DIGIT
BHI.S NOMORE ;IF NOT A DIGIT, MOVE ON
CMPI.B #'0',D3
BLT.S NOMORE ;IF NOT A DIGIT, MOVE ON
ANDI.L #$0F,D3 ;STRIP DOWN TO 4 BITS (STRIP THE ASCII)
LSL.L #1,D0 ;MULTIPLY EXISTING BINARY NUMBER BY 10
MOVE.L D0,D1 ;FIRST DOUBLE, THEN DOUBLE TWICE MORE AND ADD
LSL.L #2,D0 ;THATS THE SAME AS 2X + 8X
ADD.L D1,D0
ADD.L D3,D0 ;AND ADD IN THE NEW DECIMAL DIGIT
ADDQ.B #1,D2 ;INC # OF DIGITS EITHER SIDE OF DP
CMPI.B #8,D2 ;REACHED 8 (THE MAXIMUM HERE)?
BNE.S GETDIG ;NO, GET ANOTHER ASCII DECIMAL DIGIT
FFPERR
MOVEQ #1,D1
RTS
NOMORE
MOVE.L A0,A5 ;SAVE POINTER TO NEXT #
JSR LVO.SPFLT(A3) ;MAKE THIS # INTO FLOATING POINT
TST.L D4
BEQ JUSTLEFT ;SKIP FRACTIONIZING IF THERES NO FRACTION
SUBQ.L #1,D2
BMI.S JUSTLEFT
FRACTIONIZE ;DIVIDE BY 10 ONCE FOR EACH DIGIT RIGHT OF THE DP
MOVE.L #$A0000044,D1
JSR LVO.SPDIV(A3)
DBRA D2,FRACTIONIZE ;D2 IS THE DIGIT COUNT FOR THE FRACTIONAL PART
JUSTLEFT
EOR.L D5,D0 ;SET THE SIGN
CLR.L D1 ;NO ERROR
RTS
DATA
CNOP 0,4 ;ALIGN TO LONGWORD
DECBUF ;THIS IS TRICKY
DC.B 10,' ' ;START WITH LINEFEED AND SPACE
DECBUF2
DC.B ' 0' ;ROOM FOR NEG SIGN AND FIRST 0
MATHNAME
DC.B 'mathffp.library' ;THIS AREA USED AS PART OF DECBUF, ALSO!!
DC.B 0,10,10,10 ;A FEW LINEFEEDS
EVEN
DOSNAME
DC.B 'dos.library',0
EVEN
END